package org.evil.dog.gateway.filter;

import lombok.extern.log4j.Log4j2;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;

import java.net.URI;

/**
 * @Author: 阿巳的狗
 * @Des: 网关错误处理类
 * @Date: 2021-04-30
 */

@Log4j2
public class DogGatewayFilter {

    private final String IP = "app-client-ip";

    private final String X_FORWARDED_FOR = "X-Forwarded-For";

    /**
     *  系统换行符，用于日志打印
     */
    private final String LINE_SEPARATOR = System.getProperty("line.separator");

    protected LoadBalancerClient loadBalancer;

    protected String getRealURL(ServerWebExchange exchange) {
        //获取路由地址
        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        if (route == null) {
            return null;
        }
        URI url = route.getUri();
        if (url == null || !"lb".equals(url.getScheme())) {
            return url != null ? url.toString() : "";
        } else {
            ServiceInstance instance = this.loadBalancer.choose(url.getHost());
            if (instance == null) {
                return null;
            } else {
                return instance.getUri().toString();
            }
        }
    }

    protected void writeErrLog(ServerWebExchange exchange, String msg) {
        ServerHttpRequest request = exchange.getRequest();
        //获取真实地址
        String realUrl = this.getRealURL(exchange);
        //客户端IP
        String appClientIP = request.getHeaders().getFirst(IP);
        String ipChains = request.getHeaders().getFirst(X_FORWARDED_FOR);
        if (appClientIP == null) {
            appClientIP = request.getRemoteAddress().getHostString();
            request = exchange.getRequest().mutate().header(IP, appClientIP).build();
        }
        //api接口地址
        String apiPath = request.getURI().getPath();
        StringBuilder logBuilder=new StringBuilder(LINE_SEPARATOR);
        logBuilder.append("============请求错误=============");
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("请求路由:" + ipChains);
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("客户端IP:" + appClientIP);
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("接口名称:" + apiPath);
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("请求方式:" + request.getMethod());
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("服务地址:" + realUrl);
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("错误描述:" + msg);
        logBuilder.append(LINE_SEPARATOR);
        logBuilder.append("=================================");
        log.info(logBuilder.toString());
    }
}
